﻿using System;
using System.Collections.Generic;
using System.Reflection;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.ExtensibleStorage;

namespace RegionSplittor.Utils.XDataUtils
{
	public class SchemaManager
	{
		public SchemaManager(SchemaData schemaData)
		{
			this.m_SchemaData = schemaData;
			this.m_SchemaBuilder = new SchemaBuilder(new Guid(this.m_SchemaData.SchemaId));
			this.m_Assembly = Assembly.GetAssembly(typeof(XYZ));
		}

		public void AddField<TypeName>(string strFieldName, UnitType unitType)
		{
			this.m_SchemaData.AddFieldData(strFieldName, typeof(TypeName), unitType);
		}

		public Schema CreateSchema()
		{
			foreach (FieldData fieldData in this.m_SchemaData.FiledData)
			{
				Type type = null;
				try
				{
					type = Type.GetType(fieldData.Type, true, true);
				}
				catch
				{
					type = this.m_Assembly.GetType(fieldData.Type);
				}
				if (!(null == type))
				{
					FieldBuilder fieldBuilder = null;
					if (type.IsGenericType)
					{
						Type genericTypeDefinition = type.GetGenericTypeDefinition();
						Type genericTypeDefinition2 = typeof(IDictionary<int, int>).GetGenericTypeDefinition();
						Type genericTypeDefinition3 = typeof(IList<int>).GetGenericTypeDefinition();
						Type[] genericArguments = type.GetGenericArguments();
						if (genericTypeDefinition == genericTypeDefinition2)
						{
							fieldBuilder = this.m_SchemaBuilder.AddMapField(fieldData.FiledName, genericArguments[0], genericArguments[1]);
						}
						else if (genericTypeDefinition == genericTypeDefinition3)
						{
							fieldBuilder = this.m_SchemaBuilder.AddArrayField(fieldData.FiledName, genericArguments[0]);
						}
					}
					else
					{
						fieldBuilder = this.m_SchemaBuilder.AddSimpleField(fieldData.FiledName, type);
					}
					if (fieldBuilder != null && fieldBuilder.NeedsUnits())
					{
						fieldBuilder.SetUnitType(fieldData.UnitType);
					}
				}
			}
			this.m_SchemaBuilder.SetSchemaName(this.m_SchemaData.SchemaName);
			this.m_SchemaBuilder.SetReadAccessLevel(this.m_SchemaData.ReadAccess);
			this.m_SchemaBuilder.SetWriteAccessLevel(this.m_SchemaData.WriteAccess);
			this.m_SchemaBuilder.SetDocumentation(this.m_SchemaData.Documentation);
			this.m_Schema = this.m_SchemaBuilder.Finish();
			return this.m_Schema;
		}

		public Schema GetSchema()
		{
			return this.m_Schema;
		}

		public static Schema GetSchema(Guid guid)
		{
			return Schema.Lookup(guid);
		}

		private SchemaData m_SchemaData;

		private SchemaBuilder m_SchemaBuilder;

		private Schema m_Schema;

		private Assembly m_Assembly;
	}
}
